package com.southwind.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 【日志】切面类
 * Created by chenhs on 2018/6/22.
 *
 * 使用Spring框架的AOP时，并不需要这么复杂，
 * 在Spring框架中，我们不需要创建动态代理类，只需要创建一个切面类
 * 1.@Aspect：表示该类是切面类。
 * 2.@Component：将该类注入到IOC容器。
 *
 */
@Aspect
@Component
public class LoggerAspect {

    /**
     * 1.@Before：表示before方法执行的时机。
     * 2.execution(public int com.southwind.aspect.CalImpl.*(..))：表示切入点是com.southwind.aspect包下CalImpl类中的所有方法。
     * 即CalImpl所有方法在执行之前会首先执行LoggerAspect类中的before方法。
     *
     * @param joinpoint
     */
    @Before("execution(public int com.southwind.aspect.CalServiceImpl.*(..))")
    public void before(JoinPoint joinpoint) {
        //获取方法名
        String name = joinpoint.getSignature().getName();
        //获取参数列表
        String args = Arrays.toString(joinpoint.getArgs());
        System.out.println(name + "的参数是：" + args);
    }

    /**
     * 表示CalImpl所有方法执行之后会执行LoggerAspect类中的after方法。
     *
     * @param joinPoint
     */
    @After("execution(public int com.southwind.aspect.CalServiceImpl.*(..))")
    public void after(JoinPoint joinPoint) {
        //获取方法名
        String name = joinPoint.getSignature().getName();
        //获取参数列表
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println(name + "方法结束");
    }

    /**
     * 表示CalImpl所有方法在return之后会执行LoggerAspect类中的afterReturn方法。
     *
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "execution(public int com.southwind.aspect.CalServiceImpl.*(..))", returning = "result")
    public void afterReturn(JoinPoint joinPoint, Object result) {
        //获取方法名
        String name = joinPoint.getSignature().getName();
        System.out.println(name + "方法的结果是：" + result);
    }

    /**
     * 表示CalImpl所有方法在抛出异常时会执行LoggerAspect类中的afterThrowing方法。
     *
     * @param joinPoint
     * @param ex
     */
    @AfterThrowing(value = "execution(public int com.southwind.aspect.CalServiceImpl.*(..))", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Exception ex) {
        //获取方法名
        String name = joinPoint.getSignature().getName();
        System.out.println(name + "方法抛出异常：" + ex);
    }
}
